/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { FileUtil } from '@ohos/hvigor';
import * as path from "path";
import * as fs from "fs";
import { ITaskContext, PathConstants } from '..';

export default class SerializationPathUtil extends FileUtil {
  static readonly sep: string = path.sep;

  static dirname(p: string): string {
    return path.dirname(p);
  }

  static basename(p: string, suffix?: string): string {
    return path.basename(p, suffix);
  }

  static extname(p: string): string {
    return path.extname(p);
  }

  static isAbsolute(p: string): boolean {
    return path.isAbsolute(p)
  }

  static normalize(p: string): string {
    return path.normalize(p)
  }

  static relative(from: string, to: string): string {
    return path.relative(from, to);
  }

  static join(...paths: string[]): string {
    return path.join(...paths);
  }

  static rmSync(path: fs.PathLike, options?: fs.RmOptions,): void {
    return fs.rmSync(path, options);
  }

  /**
   * 计算模块化导入路径
   * 将绝对文件路径转换为模块化导入路径
   *
   * @param absolutePath 绝对文件路径，例如: /project/sampleentry/src/generated/ets/model/Person.ets
   * @param context 任务上下文，提供模块名称和路径上下文
   * @returns 模块化导入路径，例如: sampleentry/ets/model/Person
   */
  static calculateModularImportPath(absolutePath: string, context: ITaskContext): string {
    const packageName = context.getPackageName();

    const moduleRelativePath = context.calculateSourceRootToModuleRoot(absolutePath);

    // 移除文件扩展名
    const pathWithoutExtension = this.removeFileExtension(moduleRelativePath);

    // 拼接模块化路径
    return `${packageName}/${pathWithoutExtension}`;
  }

  /**
   * 计算Sendable类的输出路径
   * 将原始源文件路径映射到sendableModel目录
   *
   * @param className 原始类名
   * @param context 任务上下文
   * @returns Sendable类的输出路径
   */
  static mapToSendableOutputPath(className: string, context: ITaskContext): string {
    // 获取基础输出路径（不包含文件名）
    const baseOutputDir = context.getOutputRoot();

    // 构建sendableModel目录路径
    const sendableModelDir = this.join(baseOutputDir, 'ets/sendableModel');

    // 返回完整的Sendable类文件路径
    return this.join(sendableModelDir, `Sendable${className}.ets`);
  }

  /**
   * 递归扫描目录，获取所有 ETS 文件
   *
   * @param directory 要扫描的目录路径
   * @returns 所有 ETS 文件的绝对路径数组
   */
  static scanEtsFiles(directory: string): string[] {
    const etsFiles: string[] = [];

    const deepScanEtsFiles = (scanPath: string, relativePath: string) => {
      let resolvePath = this.pathResolve(scanPath, relativePath);

      if (!this.exist(resolvePath)) {
        return;
      }

      if (this.isDictionary(resolvePath)) {
        const files: string[] = fs.readdirSync(resolvePath);
        files.forEach(file => {
          deepScanEtsFiles(resolvePath, file);
        });
      } else {
        // 只收集 .ets 文件
        if (path.extname(relativePath) === PathConstants.ETS_EXTENSIONS) {
          etsFiles.push(resolvePath);
        }
      }
    }

    deepScanEtsFiles(directory, '');

    return etsFiles;
  }

  /**
   * 移除文件扩展名
   *
   * @param filePath 文件路径
   * @returns 无扩展名的路径
   */
  private static removeFileExtension(filePath: string): string {
    const lastDotIndex = filePath.lastIndexOf('.');
    if (lastDotIndex > 0) {
      return filePath.substring(0, lastDotIndex);
    }
    return filePath;
  }
}